package com.matrix.storage.service.impl;

import com.aliyun.oss.model.OSSObjectSummary;
import com.matrix.common.context.RequestContext;
import com.matrix.common.entity.Result;
import com.matrix.common.utils.IdWorker;
import com.matrix.domain.media.oss.StorageFileDTO;
import com.matrix.storage.constant.StorageError;
import com.matrix.storage.constant.StorageSpaceConstant;
import com.matrix.storage.dto.StorageSpaceDTO;
import com.matrix.storage.entity.StorageSpace;
import com.matrix.storage.mapper.StorageSpaceMapper;
import com.matrix.storage.utils.AliOssUtil;
import com.matrix.storage.utils.FileUtil;
import com.matrix.storage.vo.StorageFileVO;
import com.matrix.storage.vo.StorageSpaceVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.matrix.storage.service.StorageSpaceService;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

@Service
public class StorageSpaceServiceImpl implements StorageSpaceService {

    @Autowired
    private AliOssUtil aliOssUtil;

    @Autowired
    private StorageSpaceMapper storageSpaceMapper;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private RequestContext requestContext;

    /**
     * 根据用户创建空间
     */
    public void createCompanyStorage() {
        //计算id
        String storageId = idWorker.nextId() + "";
        String spaceName = userSpaceName(requestContext.getCompanyId());
        //2、我的素材
        String materials = spaceName + "/" + StorageSpaceConstant.Folder_Materials + "/";
        aliOssUtil.createFolder(materials);
        //3、我的草稿
        String draft = spaceName + "/" + StorageSpaceConstant.Folder_Draft + "/";
        aliOssUtil.createFolder(draft);

        StorageSpace storageSpace = new StorageSpace();
        storageSpace.setId(storageId);
        storageSpace.setCompanyId(requestContext.getCompanyId());
        storageSpace.setCreateTime(LocalDateTime.now());
        storageSpace.setUpdateTime(LocalDateTime.now());
        storageSpace.setStatus(StorageSpaceConstant.Status_Normal);
        storageSpace.setFolderName(spaceName);
        storageSpace.setTotalCapacity(StorageSpaceConstant.TotalCapacity);
        storageSpace.setUsedCapacity(0);

        storageSpaceMapper.insert(storageSpace);
    }

    public StorageSpaceVO companyStorageSpaceInfo() {
        //TODO: 异常处理
        //1、查询
        List<StorageSpace> spaces = storageSpaceMapper.getByCompanyId(requestContext.getCompanyId());
        //2、判断个数
        if (spaces != null && !spaces.isEmpty()) {
            //3、取第一个元素
            StorageSpace space = spaces.get(0);
            StorageSpaceVO storageSpaceVO = new StorageSpaceVO();
            BeanUtils.copyProperties(space, storageSpaceVO);
            return storageSpaceVO;
        } else {
            // 处理查询不到的情况，可以选择返回null或者抛出异常
            return null; // 或 throw new SomeException("未找到用户的存储空间信息");
        }
    }

    public List<StorageFileVO> listObjects(int type) {
        //获取用户文件夹
        StorageSpaceVO storageSpaceVO = companyStorageSpaceInfo();
        String userSpace = storageSpaceVO.getFolderName();
        String moduleName = getModuleName(type);
        String keyPrefix = userSpace + "/" +  moduleName;

        List<OSSObjectSummary> ossObjectSummaries = aliOssUtil.listObjectsV2(keyPrefix);

        List<StorageFileVO> files = new ArrayList<>();
        long size = 0;
        for (OSSObjectSummary s : ossObjectSummaries) {
            size += s.getSize();
            if (s.getKey().contains(keyPrefix)) {
                StorageFileVO file = createFile(s);
                if (file != null) {
                    files.add(file);
                }
            }
        }
        //size代表了存储空间
        System.out.println(FileUtil.fileSizeStr(size));
        return files;
    }

    @Override
    public void updateCompanyStorageSpaceInfo(StorageSpaceDTO storageSpaceDTO) {
        storageSpaceMapper.update(storageSpaceDTO);
    }

    @Override
    public Result<String> upload(MultipartFile file, int type) {
        try {
            //填写Object完整路径，完整路径中不能包含Bucket名称，例如exampledir/exampleobject.txt。
            StorageSpaceVO storageSpaceVO = companyStorageSpaceInfo();
            String userSpace = storageSpaceVO.getFolderName();
            String moduleName = getModuleName(type);
            String path = userSpace + "/" + moduleName;

            //原生文件名称
            String originalFilename = file.getOriginalFilename();
            //截取原始文件名后缀
            String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
            //构造新文件名
            String fileName = UUID.randomUUID().toString() + extension;
            String objectName = path + "/" + fileName;
            String filePath = aliOssUtil.upload(file.getBytes(), objectName);
            return Result.success(filePath);
        } catch (IOException e) {
            System.out.println(e);
            //TODO: 修改常量
            return Result.error(StorageError.UPLOAD_FAIL);
        }
    }

    private String getModuleName(int type) {
        if (type == 1) {
            return StorageSpaceConstant.Folder_Draft;
        } else {
            return StorageSpaceConstant.Folder_Materials;
        }
    }

    private String userSpaceName(String companyId) {
        //matrix-bucket-id的32位置md5-随机4位数字-release
        String prefix = "u-";
//        String idMd5 = new Md5Hash(uid).toString().toLowerCase();
        String idMd5 = "";
//        String randomStr = generateRandomString(4);
        return prefix + idMd5 + generateRandomString(4);
    }

    private String generateRandomString(int length) {
        String charPool = "0123456789abcdefghijklmnopqrstuvwxyz";
        Random rand = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int randomIndex = rand.nextInt(charPool.length());
            sb.append(charPool.charAt(randomIndex));
        }
        return sb.toString();
    }

    private StorageFileVO createFile(OSSObjectSummary summary) {
        String key = summary.getKey();
        System.out.println(key);
        if (FileUtil.isValidFile(key)) {
            StorageFileVO file = new StorageFileVO();
            file.setUpdateTS(summary.getLastModified().getTime());
            file.setETag(summary.getETag());
            StringBuilder stringBuilder = new StringBuilder("https://");
            stringBuilder
                    .append(aliOssUtil.bucketName())
                    .append(".")
                    .append(aliOssUtil.endPoint())
                    .append("/")
                    .append(key);
            file.setFileURLString(stringBuilder.toString());
            file.setSnapshot(snapshot(key));
            return file;
        }
        return null;
    }

    private String snapshot(String objectKey) {
        if (FileUtil.isVideo(objectKey)) {
            //视频封面
            StringBuilder stringBuilder = new StringBuilder("https://");
            stringBuilder
                    .append(aliOssUtil.bucketName())
                    .append(".")
                    .append(aliOssUtil.endPoint())
                    .append("/")
                    .append(objectKey)
                    .append("?")
                    .append("x-oss-process=video/snapshot,t_10000,f_jpg");
            return stringBuilder.toString();
        } else if (FileUtil.isImage(objectKey)) {
            //图片封面：图片的地址
            StringBuilder stringBuilder = new StringBuilder("https://");
            stringBuilder
                    .append(aliOssUtil.bucketName())
                    .append(".")
                    .append(aliOssUtil.endPoint())
                    .append("/")
                    .append(objectKey);
            return stringBuilder.toString();
        } else if (FileUtil.isAudio(objectKey)) {
            //音频封面：固定的默认图
            return "";
        } else {
            return "";
        }
    }
}
